baba7ef3c62a50228b8bb6f8439a9353766ba8f8
[openwrt/openwrt.git] /
1 From b5ade0e0e1c1622a85fbfd2c93b41caff479f305 Mon Sep 17 00:00:00 2001
2 From: Florian Maurer <f.maurer@outlook.de>
3 Date: Fri, 3 Oct 2025 12:56:13 +0200
4 Subject: [PATCH] ath11k: add ath11k_mac_op_flush_sta to properly flush pending
5 packets
6
7 When a STA is marked as no longer authorized, if the driver doesn't
8 implement flush_sta(), mac80211 calls ieee80211_flush_queues() to
9 flush hardware queues to avoid sending unencrypted frames.
10
11 This has became a problem for ath11k because ieee80211_flush_queues()
12 will stop all traffic and call ath11k_flush, which waits until the
13 whole HW queue is empty. In a busy environment this will trigger a
14 timeout warning and stalls other STAs.
15
16 Fix this by implementing flush_sta method using WMI command to flush
17 frames of a specific STA.
18 Flushed frames will be marked as discard in tx complete indication.
19
20 warning print "ath11k c000000.wifi: failed to flush transmit queue 0"
21 was observed on various openwrt devices, and is fixed through this patch.
22
23 Tested-by: Florian Maurer <f.maurer@outlook.de>
24 Tested-by: Flole <flole@flole.de>
25 Co-developed-by: Benjamin Berg <benjamin@sipsolutions.net>
26 Signed-off-by: Benjamin Berg <benjamin@sipsolutions.net>
27 Signed-off-by: Florian Maurer <f.maurer@outlook.de>
28 ---
29 drivers/net/wireless/ath/ath11k/mac.c | 18 ++++++++++++++++++
30 1 file changed, 18 insertions(+)
31
32 --- a/drivers/net/wireless/ath/ath11k/mac.c
33 +++ b/drivers/net/wireless/ath/ath11k/mac.c
34 @@ -8248,6 +8248,23 @@ static void ath11k_mac_op_flush(struct i
35 ath11k_mac_flush_tx_complete(ar);
36 }
37
38 +static void ath11k_mac_op_flush_sta(struct ieee80211_hw *hw,
39 + struct ieee80211_vif *vif,
40 + struct ieee80211_sta *sta)
41 +{
42 + struct ath11k_vif *arvif = (void *)vif->drv_priv;
43 + struct ath11k *ar = hw->priv;
44 + struct peer_flush_params params = {
45 + .peer_tid_bitmap = 0xFF,
46 + .vdev_id = arvif->vdev_id,
47 + };
48 + int ret;
49 +
50 + ret = ath11k_wmi_send_peer_flush_tids_cmd(ar, sta->addr, &params);
51 + if (ret)
52 + ath11k_warn(ar->ab, "failed to flush sta %pM: %d\n", sta->addr, ret);
53 +}
54 +
55 static bool
56 ath11k_mac_has_single_legacy_rate(struct ath11k *ar,
57 enum nl80211_band band,
58 @@ -9823,6 +9840,7 @@ static const struct ieee80211_ops ath11k
59 .set_bitrate_mask = ath11k_mac_op_set_bitrate_mask,
60 .get_survey = ath11k_mac_op_get_survey,
61 .flush = ath11k_mac_op_flush,
62 + .flush_sta = ath11k_mac_op_flush_sta,
63 .sta_statistics = ath11k_mac_op_sta_statistics,
64 CFG80211_TESTMODE_CMD(ath11k_tm_cmd)
65